﻿#include "StdAfx.h"

namespace DuiLib {

CDelegateBase::CDelegateBase(void *pObject, void *pFn)
{
    m_pObject = pObject;
    m_pFn = pFn;
}

CDelegateBase::CDelegateBase(const CDelegateBase &rhs)
{
    m_pObject = rhs.m_pObject;
    m_pFn = rhs.m_pFn;
}

CDelegateBase::~CDelegateBase()
{

}

bool CDelegateBase::Equals(const CDelegateBase &rhs) const
{
    return m_pObject == rhs.m_pObject && m_pFn == rhs.m_pFn;
}

bool CDelegateBase::operator()(void *param)
{
    return Invoke(param);
}

void *CDelegateBase::GetFn()
{
    return m_pFn;
}

void *CDelegateBase::GetObject()
{
    return m_pObject;
}

CEventSource::~CEventSource()
{
    for (int i = 0; i < m_aDelegates.GetSize(); i++)
    {
        CDelegateBase *pObject = static_cast<CDelegateBase *>(m_aDelegates[i]);

        if (pObject) { delete pObject; }
    }
}

CEventSource::operator bool()
{
    return m_aDelegates.GetSize() > 0;
}

void CEventSource::operator+= (const CDelegateBase &d)
{
    for (int i = 0; i < m_aDelegates.GetSize(); i++)
    {
        CDelegateBase *pObject = static_cast<CDelegateBase *>(m_aDelegates[i]);

        if (pObject && pObject->Equals(d)) { return; }
    }

    m_aDelegates.Add(d.Copy());
}

void CEventSource::operator+= (FnType pFn)
{
    (*this) += MakeDelegate(pFn);
}

void CEventSource::operator-= (const CDelegateBase &d)
{
    for (int i = 0; i < m_aDelegates.GetSize(); i++)
    {
        CDelegateBase *pObject = static_cast<CDelegateBase *>(m_aDelegates[i]);

        if (pObject && pObject->Equals(d))
        {
            delete pObject;
            m_aDelegates.Remove(i);
            return;
        }
    }
}
void CEventSource::operator-= (FnType pFn)
{
    (*this) -= MakeDelegate(pFn);
}

bool CEventSource::operator()(void *param)
{
    for (int i = 0; i < m_aDelegates.GetSize(); i++)
    {
        CDelegateBase *pObject = static_cast<CDelegateBase *>(m_aDelegates[i]);

        if (pObject && !(*pObject)(param)) { return false; }
    }

    return true;
}

} // namespace DuiLib
